package com.ruixin.parser;

import com.ruixin.annotation.Parser;
import com.ruixin.annotation.Property;
import com.ruixin.base.BaseParser;
import com.ruixin.base.exception.BaseException;
import com.ruixin.base.proxy.ProxyHelper;
import com.ruixin.base.util.BeanUtil;
import com.ruixin.base.util.StringUtil;
import com.ruixin.config.ApplicationContext;
import com.ruixin.config.Environment;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.Properties;

@Parser(annotation = Property.class)
public class PropertyParser extends BaseParser<ApplicationContext> {

    public PropertyParser(ApplicationContext context, Class<? extends Annotation> type) {
        super(context, type);
    }

    @Override
    public void parseClass(Class<?> clz) throws BaseException {
        super.parseClass(clz);
        Property annotation = BeanUtil.getAnnotation(clz, Property.class);
        String file = annotation.file();
        String prefix = annotation.prefix();
        Object bean = this.context.getBean(clz);
        if(bean==null){
            String beanName = annotation.value();
            if(StringUtil.isBlackOrNull(beanName)){
                beanName = annotation.name();
                if(StringUtil.isBlackOrNull(beanName)){
                    beanName = BeanUtil.getDefaultBeanName(clz);
                }
            }
            bean = ProxyHelper.newProxyInstance(clz);
            this.context.addBean(beanName,bean);
        }

        Field[] fields = clz.getDeclaredFields();
        Properties properties = null;
        if(StringUtil.isNotBlackOrNull(file)){
            properties = BeanUtil.getProperties(file);
        }else{
            Environment environment = this.context.getEnvironment();
            properties = environment.getProperties();
        }
        for (Field field : fields) {
            String name = field.getName();
            if(StringUtil.isNotBlackOrNull(prefix)){
                name = prefix+"."+name;
            }
            if(properties.containsKey(name)){
                field.setAccessible(true);
                BeanUtil.invokeField(bean,field,properties.getProperty(name));
            }
        }
    }
}
